2 Problem: 11504 - Dominos
3 Author: Andrés Mejía-Posada
4 (http://blogaritmo.factorcomun.org)
18 vector
<int> g
[N
], gt
[N
];
20 int visited
[N
], scc
[N
], color
[N
];
22 void dfs(int u
, int mark
, deque
<int> *in_order
, int visited
[], vector
<int> g
[]){
25 vector
<int> &out
= g
[u
];
26 for (int k
=0, m
=out
.size(); k
<m
; ++k
){
28 if (!visited
[v
]) dfs(v
, mark
, in_order
, visited
, g
);
30 if (in_order
) in_order
->push_front(u
);
33 enum { standing
, tiled
, handed
};
34 void shoot(int u
, int root
, set
<int> g
[]){
35 if (u
== root
) color
[u
] = handed
;
36 else color
[u
] = tiled
;
39 for (set
<int>::iterator k
=out
.begin(); k
!=out
.end(); ++k
){
40 if (color
[*k
] == handed
&& *k
!= root
) color
[*k
] = tiled
;
41 else if (color
[*k
] == standing
) shoot(*k
, root
, g
);
49 int n
, m
; cin
>> n
>> m
;
51 for (int i
=0; i
<=n
; ++i
) g
[i
].clear(), gt
[i
].clear(), gc
[i
].clear(), visited
[i
] = scc
[i
] = color
[i
] = 0;
53 for (int u
, v
, i
=0; i
<m
&& cin
>> u
>> v
; ++i
) g
[u
].push_back(v
), gt
[v
].push_back(u
);
57 for (int i
=1; i
<=n
; ++i
)
59 dfs(i
, 1, &in_order
, visited
, g
);
63 for (deque
<int>::iterator i
=in_order
.begin(); i
!=in_order
.end(); ++i
)
65 dfs(*i
, id
++, NULL
, scc
, gt
);
69 for (int i=0; i<=n; ++i){
70 printf("ssc[%d] = %d\n", i, scc[i]);
76 Build strongly connected components graph in gc.
78 for (int i
=1; i
<=n
; ++i
){
79 vector
<int> &out
= g
[i
];
80 for (int k
=0, m
=out
.size(); k
<m
; ++k
){
81 gc
[scc
[i
]].insert(scc
[out
[k
]]);
85 for(int i
=1; i
<id
; ++i
){
92 for (int i
=1; i
<id
; ++i
){
93 ans
+= (color
[i
] == handed
);
103 Explicación del algoritmo:
105 Lo primero es ver que cada componente fuertemente conexa del grafo puede
106 tumbarse completamente usando solo una ficha. Entonces primero reducimos
107 el grafo a un DAG donde cada nodo representa una componente fuertemente
108 conexa del grafo original.
110 Para encontrar la respuesta utilizamos el siguiente algoritmo:
111 Tumbamos cada ficha a mano y seguimos el efecto dominó. Si alcanzamos
112 otra ficha que había sido tumbada a mano, entonces esta segunda no necesita